#pragma once
#include "stdint.h"

#ifndef _u
#ifdef __ASSEMBLER__
#define _u(x) x
#else
#define _u(x) x ## u
#endif
#endif
#define SIO_CPUID_OFFSET _u(0x00000000)
#define SIO_CPUID_BITS   _u(0xffffffff)
#define SIO_CPUID_RESET  "-"
#define SIO_CPUID_MSB    _u(31)
#define SIO_CPUID_LSB    _u(0)
#define SIO_CPUID_ACCESS "RO"
#define __force_inline __always_inline

typedef enum {
/* =======================================  ARM Cortex-M0+ Specific Interrupt Numbers  ======================================= */
  Reset_IRQn                = -15,              /*!< -15  Reset Vector, invoked on Power up and warm reset                     */
  NonMaskableInt_IRQn       = -14,              /*!< -14  Non maskable Interrupt, cannot be stopped or preempted               */
  HardFault_IRQn            = -13,              /*!< -13  Hard Fault, all classes of Fault                                     */
  SVCall_IRQn               =  -5,              /*!< -5 System Service Call via SVC instruction                                */
  PendSV_IRQn               =  -2,              /*!< -2 Pendable request for system service                                    */
  SysTick_IRQn              =  -1,              /*!< -1 System Tick Timer                                                      */
/* ===========================================  RP2040 Specific Interrupt Numbers  =========================================== */
  TIMER_IRQ_0_IRQn          =   0,              /*!< 0  TIMER_IRQ_0                                                            */
  TIMER_IRQ_1_IRQn          =   1,              /*!< 1  TIMER_IRQ_1                                                            */
  TIMER_IRQ_2_IRQn          =   2,              /*!< 2  TIMER_IRQ_2                                                            */
  TIMER_IRQ_3_IRQn          =   3,              /*!< 3  TIMER_IRQ_3                                                            */
  PWM_IRQ_WRAP_IRQn         =   4,              /*!< 4  PWM_IRQ_WRAP                                                           */
  USBCTRL_IRQ_IRQn          =   5,              /*!< 5  USBCTRL_IRQ                                                            */
  XIP_IRQ_IRQn              =   6,              /*!< 6  XIP_IRQ                                                                */
  PIO0_IRQ_0_IRQn           =   7,              /*!< 7  PIO0_IRQ_0                                                             */
  PIO0_IRQ_1_IRQn           =   8,              /*!< 8  PIO0_IRQ_1                                                             */
  PIO1_IRQ_0_IRQn           =   9,              /*!< 9  PIO1_IRQ_0                                                             */
  PIO1_IRQ_1_IRQn           =  10,              /*!< 10 PIO1_IRQ_1                                                             */
  DMA_IRQ_0_IRQn            =  11,              /*!< 11 DMA_IRQ_0                                                              */
  DMA_IRQ_1_IRQn            =  12,              /*!< 12 DMA_IRQ_1                                                              */
  IO_IRQ_BANK0_IRQn         =  13,              /*!< 13 IO_IRQ_BANK0                                                           */
  IO_IRQ_QSPI_IRQn          =  14,              /*!< 14 IO_IRQ_QSPI                                                            */
  SIO_IRQ_PROC0_IRQn        =  15,              /*!< 15 SIO_IRQ_PROC0                                                          */
  SIO_IRQ_PROC1_IRQn        =  16,              /*!< 16 SIO_IRQ_PROC1                                                          */
  CLOCKS_IRQ_IRQn           =  17,              /*!< 17 CLOCKS_IRQ                                                             */
  SPI0_IRQ_IRQn             =  18,              /*!< 18 SPI0_IRQ                                                               */
  SPI1_IRQ_IRQn             =  19,              /*!< 19 SPI1_IRQ                                                               */
  UART0_IRQ_IRQn            =  20,              /*!< 20 UART0_IRQ                                                              */
  UART1_IRQ_IRQn            =  21,              /*!< 21 UART1_IRQ                                                              */
  ADC_IRQ_FIFO_IRQn         =  22,              /*!< 22 ADC_IRQ_FIFO                                                           */
  I2C0_IRQ_IRQn             =  23,              /*!< 23 I2C0_IRQ                                                               */
  I2C1_IRQ_IRQn             =  24,              /*!< 24 I2C1_IRQ                                                               */
  RTC_IRQ_IRQn              =  25               /*!< 25 RTC_IRQ                                                                */
} IRQn_Type;

#define __CM0PLUS_REV                 0x0001U   /*!< CM0PLUS Core Revision                                                     */
#define __NVIC_PRIO_BITS               2        /*!< Number of Bits used for Priority Levels                                   */
#define __Vendor_SysTickConfig         0        /*!< Set to 1 if different SysTick Config is used                              */
#define __VTOR_PRESENT                 1        /*!< Set to 1 if CPU supports Vector Table Offset Register                     */
#define __MPU_PRESENT                  1        /*!< MPU present                                                               */
#define __FPU_PRESENT                  0        /*!< FPU present                                                               */

// ROM
#define ROM_BASE					0x00000000
// FLASH
#define XIP_BASE					0x10000000
#define XIP_NOALLOC_BASE			0x11000000
#define XIP_NOCACHE_BASE			0x12000000
#define XIP_NOCACHE_NOALLOC_BASE	0x13000000
#define XIP_CTRL_BASE				0x14000000
#define XIP_SRAM_BASE				0x15000000
#define XIP_SRAM_END				0x15004000
#define XIP_SSI_BASE				0x18000000
// SRAM
#define SRAM_BASE					0x20000000
#define SRAM_STRIPED_BASE			0x20000000
#define SRAM_STRIPED_END			0x20040000
#define SRAM4_BASE					0x20040000
#define SRAM5_BASE					0x20041000
#define SRAM_END					0x20042000
#define SRAM0_BASE					0x21000000
#define SRAM1_BASE					0x21010000
#define SRAM2_BASE					0x21020000
#define SRAM3_BASE					0x21030000
// APB
#define SYSINFO_BASE				0x40000000
#define SYSCFG_BASE					0x40004000
#define CLOCKS_BASE					0x40008000
#define RESETS_BASE					0x4000C000
#define PSM_BASE					0x40010000
#define IO_BANK0_BASE				0x40014000
#define IO_QSPI_BASE				0x40018000
#define PADS_BANK0_BASE				0x4001C000
#define PADS_QSPI_BASE				0x40020000
#define XOSC_BASE					0x40024000
#define PLL_SYS_BASE				0x40028000
#define PLL_USB_BASE				0x4002C000
#define BUSCTRL_BASE				0x40030000
#define UART0_BASE					0x40034000
#define UART1_BASE					0x40038000
#define SPI0_BASE					0x4003C000
#define SPI1_BASE					0x40040000
#define I2C0_BASE					0x40044000
#define I2C1_BASE					0x40048000
#define ADC_BASE					0x4004C000
#define PWM_BASE					0x40050000
#define TIMER_BASE					0x40054000
#define WATCHDOG_BASE				0x40058000
#define RTC_BASE					0x4005C000
#define ROSC_BASE					0x40060000
#define VREG_AND_CHIP_RESET_BASE	0x40064000
#define TBMAN_BASE					0x4006C000
// AHB
#define DMA_BASE					0x50000000
#define USBCTRL_BASE				0x50100000
#define USBCTRL_DPRAM_BASE			0x50100000
#define USBCTRL_REGS_BASE			0x50110000
#define PIO0_BASE					0x50200000
#define PIO1_BASE					0x50300000
#define XIP_AUX_BASE				0x50400000
// SIO
#define SIO_BASE					0xD0000000
// CM0+ internal peripherals
#define PPB_BASE					0xE0000000

#define _REG_(x)


typedef volatile uint64_t io_rw_64;
typedef const volatile uint64_t io_ro_64;
typedef volatile uint64_t io_wo_64;
typedef volatile uint32_t io_rw_32;
typedef const volatile uint32_t io_ro_32;
typedef volatile uint32_t io_wo_32;
typedef volatile uint16_t io_rw_16;
typedef const volatile uint16_t io_ro_16;
typedef volatile uint16_t io_wo_16;
typedef volatile uint8_t io_rw_8;
typedef const volatile uint8_t io_ro_8;
typedef volatile uint8_t io_wo_8;

typedef volatile uint8_t *const ioptr;
typedef ioptr const const_ioptr;

typedef unsigned int uint;
// typedef unsigned int uint32_t;
// typedef unsigned short uint16_t;
// typedef unsigned char uint8_t;

#define __IO volatile

#define IO_RD(addr)            *((volatile uint32_t*)(addr))
#define IO_WR(addr, data)      *((volatile uint32_t*)(addr)) = (data)


#define  get_core_num() (*(uint32_t *) (0xD0000000))
 
